
#if !CF && !SILVERLIGHT

using System;
using Qdb.Config;
using Qdb.CS.Foundation;
using Qdb.CS.Monitoring;
using Qdb.Internal;
using Qdb.Internal.Config;
using Qdb.IO;
using Qdb.Monitoring;
using Qdb.Tests.Optional.Monitoring.CS;
using QdbUnit;
using QdbUnit.Extensions.Fixtures;

namespace Qdb.Tests.CLI1.Monitoring
{
	public class ClientNetworkingPerformanceCounterTestCase : PerformanceCounterTestCaseBase, IOptOutMultiSession
	{
#if !NET_3_5
        private delegate TResult Func<T, TResult>(T arg);
        private delegate TResult Func<TResult>();
#endif

        private const int ByteCount = 100;

		protected override void Configure(IConfiguration config)
		{
			IFileConfiguration fileConfig = QdbLegacyConfigurationBridge.AsFileConfiguration((Config4Impl) config);
			fileConfig.Storage = new MemoryStorage();
		}

		public void TestBytesSent()
		{
			Action<ISocket4> operation = delegate(ISocket4 socket) { socket.Write(null, 0, ByteCount); };
			Func<CountingSocket4, double> expectatedValueRetriever = delegate(CountingSocket4 s) { return s.BytesSent(); };
            Func<IObjectContainer, double> actualValueRetriever = delegate(IObjectContainer container) { return PerformanceCounterSpec.NetBytesSentPerSec.PerformanceCounter(container).RawValue; };

			AssertCounter(operation, expectatedValueRetriever, actualValueRetriever);
		}

		public void TestBytesReceived()
		{
			Action<ISocket4> operation = delegate(ISocket4 socket) { socket.Read(null, 0, ByteCount); };
			Func<CountingSocket4, double> expectatedValueRetriever = delegate(CountingSocket4 s) { return s.BytesReceived(); };
            Func<IObjectContainer, double> actualValueRetriever = delegate(IObjectContainer container) { return PerformanceCounterSpec.NetBytesReceivedPerSec.PerformanceCounter(container).RawValue; };

			AssertCounter(operation, expectatedValueRetriever, actualValueRetriever);
		}

		private void AssertCounter(Action<ISocket4> operation, Func<CountingSocket4, double> expectedValueRetriever, Func<IObjectContainer, double> actualValueRetriever)
		{
			ObjectContainerBase container = (ObjectContainerBase) Db();
			container.WithEnvironment(delegate
			{
				CountingSocket4 countingSocket = new CountingSocket4(new NullSocket());
			    ISocket4 socket = new MonitoredClientSocket4(countingSocket);
			    
				operation(socket);

				Assert.AreEqual(ByteCount, expectedValueRetriever(countingSocket));
			    Assert.AreEqual(ByteCount, actualValueRetriever(container));
			});
		}
	}
}

#endif